package com.tetris.entities;

import java.awt.Graphics;
import java.awt.Color;

import com.tetris.controller.Controller;
import static com.tetris.util.Constants.*;

/**
 * 
 * @author 吴松 create the file at 2013-4-7 <br>
 * is com.itcast.tetris.entities.Ground <br>
 * Des : 地形类，做容器内部的图形判断和操作(包括判断移动的图形是否越界，绘制容器的障碍物，控制容器堆积图形的消长)
 */
public class Ground {
	
	private Color[][] obstacles = new Color[GAME_WIDTH][GAME_HEIGHT];

	private Controller controller;

	//游戏面板下落的的图形接触到固定障碍物，就将图形加入到固定地形
	public void accept(Shape shape){
		int size = shape.getShapeData().getShapeSize();
		for(int x = 0; x < size; x++){
			for(int y = 0; y < size; y++){
				if(shape.isMember(x, y) 
						&& shape.getLeft()+x>=0 && shape.getLeft()+x<GAME_WIDTH
						&& shape.getTop()+y>=0  && shape.getTop()+y<GAME_HEIGHT){
					obstacles[shape.getLeft()+x][shape.getTop()+y] = shape.getColor();
				}
			}
		}
		deleteFullLine();
	}
	
	//游戏面板下落的的图形接触到固定障碍物，当该图形加入到固定地形后，地形图形重绘
	public void drawShape(Graphics g){
		for(int x = 0; x < GAME_WIDTH; x++){
			for(int y = 0; y < GAME_HEIGHT; y++){
				if(obstacles[x][y]!=null){
					g.setColor(obstacles[x][y]);
					g.fill3DRect(x*CELL_Size, y*CELL_Size, 
							CELL_Size, CELL_Size, true);
				}
			}
		}
	}
	
	private void deleteFullLine(){
		//满行在下部，所有以Y轴开始，并从最大坐标递减
		int lines = 0;
		for(int y = GAME_HEIGHT - 1; y >= 0; y--){
			boolean isFull = true;
			for(int x = 0; x<GAME_WIDTH; x++){
				if(obstacles[x][y]==null){	//表示有空白格子
					isFull = false;
				}
			}
			if(isFull){
				//执行删除方法
				deleLine(y);
				y++;
				lines++;
			}
		}
		this.controller.onDeleteLines(lines);
	}
	
	//只删除一行(1:让y轴整体下移一格；第一行格子格子重置为0)
	private void deleLine(int lineNum){
		for(int y = lineNum; y >0; y--){
			for(int x = 0; x < GAME_WIDTH; x++){
				obstacles[x][y] = obstacles[x][y-1];	//让Y轴本行格子等于上一行格子状态
			}
		}
		//第一行格子全部空白,其实第一行(永远不会有格子，因为当第一行有格子时，表示游戏失败)
		for(int x = 0; x < GAME_WIDTH; x++){
			obstacles[x][0] = null;	
		}
	}
	
	//判断游戏是否结束，依据是障碍物第一行是否有空行,true表示结束，false表示没有结束
	public Boolean isGameOver(){
		boolean over = false;	
		for(int x = 0; x < GAME_WIDTH; x++){
			if(obstacles[x][0]!=null){
				over = true;
			}
		}
		return over;
	}
	
	//判断图形是否可以移动
	public Boolean isMoveable(Shape shape, int action){
		int top = shape.getTop();
		int left = shape.getLeft();
		//得到图形下一步动作的参数
		switch (action) {
			case Shape.RIGHT:
				left++;
				break;
			case Shape.LEFT:
				left--;
				break;
			case Shape.DOWN:
				top++;
				break;
		}
		//判断下一步的动作是否超越容器边界，若没有，做可以做，否则不可以
		int size = shape.getShapeData().getShapeSize();
		for (int x = 0; x < size; x++) {
			for (int y = 0; y < size; y++) {
				//得到当前容器内的坐标是否在图形内
				if(shape.isMember(x, y) && top+y>=0){
					if( top+y >= GAME_HEIGHT || 
							left+x < 0 ||
							left+x >= GAME_WIDTH || 
							obstacles[left+x][top+y] != null )
						return false;
				}
			}
		}
		return true;
	}

	/**
	 * 检查该位置是否是空的，是可以下落的
	 */
	public boolean positionIsEmpty(int x, int y){
		return obstacles[x][y]==null;
	}

	public void setController(Controller controller){
		this.controller = controller;
	}

	public void clearObstacles(){
		for (int i = 0; i < obstacles.length; i++) {
			for (int j = 0; j < obstacles[i].length; j++) {
				obstacles[i][j] = null;
			}
		}
	}
}
